"""
优先级路由策略

基于预定义的优先级列表选择数据源适配器。

策略特点：
1. 简单直接，易于理解和配置
2. 支持动态调整优先级
3. 支持故障转移（自动选择下一优先级）
4. 适用于有明确偏好的场景

使用场景：
- 优先使用免费数据源，付费数据源作为备选
- 优先使用高质量数据源
- 优先使用低延迟数据源

作者: RedFire Team
创建日期: 2025-10-06
版本: v1.0
"""

from typing import List, Dict, Optional
import logging

from app.routing.strategy import (
    RoutingStrategy,
    RoutingContext,
    RoutingResult,
    RoutingPriority
)


class PriorityRoutingStrategy(RoutingStrategy):
    """
    优先级路由策略
    
    按照预定义的优先级顺序选择适配器。
    
    配置示例：
    ```python
    strategy = PriorityRoutingStrategy(
        priority_list=["tushare", "akshare", "yfinance"],
        enable_fallback=True
    )
    ```
    """
    
    def __init__(
        self,
        priority_list: List[str],
        enable_fallback: bool = True,
        fallback_limit: int = 3,
        logger: Optional[logging.Logger] = None
    ):
        """
        初始化优先级路由策略
        
        Args:
            priority_list: 优先级列表（从高到低）
            enable_fallback: 是否启用故障转移
            fallback_limit: 最多返回多少个备选项
            logger: 日志记录器
        """
        super().__init__(
            name="priority",
            priority=RoutingPriority.HIGH,
            logger=logger
        )
        self.priority_list = priority_list
        self.enable_fallback = enable_fallback
        self.fallback_limit = fallback_limit
        
        self.logger.info(
            f"优先级路由策略初始化: "
            f"优先级={priority_list}, "
            f"故障转移={enable_fallback}"
        )
    
    async def select_adapter(
        self,
        context: RoutingContext,
        available_adapters: List[str]
    ) -> RoutingResult:
        """
        按优先级选择适配器
        
        Args:
            context: 路由上下文
            available_adapters: 可用的适配器列表
        
        Returns:
            RoutingResult: 路由结果
        """
        if not available_adapters:
            return RoutingResult(
                routing_reason="没有可用的适配器",
                confidence_score=0.0
            )
        
        # 考虑用户偏好
        if context.preferred_providers:
            preferred_list = context.preferred_providers + self.priority_list
        else:
            preferred_list = self.priority_list
        
        # 过滤排除的数据源
        filtered_adapters = [
            adapter for adapter in available_adapters
            if not context.is_provider_excluded(adapter)
        ]
        
        if not filtered_adapters:
            return RoutingResult(
                routing_reason="所有适配器都被排除",
                confidence_score=0.0
            )
        
        # 查找第一个可用且符合优先级的适配器
        primary_adapter = None
        fallback_adapters = []
        
        for adapter_name in preferred_list:
            if adapter_name in filtered_adapters:
                if primary_adapter is None:
                    primary_adapter = adapter_name
                elif self.enable_fallback and len(fallback_adapters) < self.fallback_limit:
                    fallback_adapters.append(adapter_name)
        
        # 如果优先级列表中没有找到，使用第一个可用的
        if primary_adapter is None:
            primary_adapter = filtered_adapters[0]
            if self.enable_fallback:
                fallback_adapters = filtered_adapters[1:self.fallback_limit + 1]
            
            return RoutingResult(
                primary_adapter=primary_adapter,
                fallback_adapters=fallback_adapters,
                routing_reason="使用默认可用适配器（不在优先级列表中）",
                confidence_score=0.6
            )
        
        return RoutingResult(
            primary_adapter=primary_adapter,
            fallback_adapters=fallback_adapters,
            routing_reason=f"基于优先级选择: {preferred_list}",
            confidence_score=1.0
        )
    
    def set_priority_list(self, priority_list: List[str]):
        """
        更新优先级列表
        
        Args:
            priority_list: 新的优先级列表
        """
        old_list = self.priority_list
        self.priority_list = priority_list
        self.logger.info(f"优先级列表已更新: {old_list} -> {priority_list}")
    
    def add_to_priority(self, adapter_name: str, position: int = -1):
        """
        添加适配器到优先级列表
        
        Args:
            adapter_name: 适配器名称
            position: 插入位置（-1表示末尾）
        """
        if adapter_name in self.priority_list:
            self.logger.warning(f"适配器已在优先级列表中: {adapter_name}")
            return
        
        if position == -1 or position >= len(self.priority_list):
            self.priority_list.append(adapter_name)
        else:
            self.priority_list.insert(position, adapter_name)
        
        self.logger.info(f"添加到优先级列表: {adapter_name} at position {position}")
    
    def remove_from_priority(self, adapter_name: str) -> bool:
        """
        从优先级列表中移除适配器
        
        Args:
            adapter_name: 适配器名称
        
        Returns:
            bool: 是否移除成功
        """
        if adapter_name not in self.priority_list:
            return False
        
        self.priority_list.remove(adapter_name)
        self.logger.info(f"从优先级列表移除: {adapter_name}")
        return True
    
    def get_priority_rank(self, adapter_name: str) -> Optional[int]:
        """
        获取适配器的优先级排名
        
        Args:
            adapter_name: 适配器名称
        
        Returns:
            Optional[int]: 排名（从0开始），不在列表中返回None
        """
        try:
            return self.priority_list.index(adapter_name)
        except ValueError:
            return None
    
    def __repr__(self) -> str:
        return (
            f"<PriorityRoutingStrategy("
            f"priority_list={self.priority_list}, "
            f"fallback={self.enable_fallback}"
            f")>"
        )


class DynamicPriorityRoutingStrategy(PriorityRoutingStrategy):
    """
    动态优先级路由策略
    
    可以根据适配器性能动态调整优先级。
    
    特性：
    - 自动降级性能差的适配器
    - 自动升级性能好的适配器
    - 基于历史数据做决策
    """
    
    def __init__(
        self,
        initial_priority_list: List[str],
        performance_threshold: float = 0.8,
        adjustment_enabled: bool = True,
        logger: Optional[logging.Logger] = None
    ):
        """
        初始化动态优先级路由策略
        
        Args:
            initial_priority_list: 初始优先级列表
            performance_threshold: 性能阈值
            adjustment_enabled: 是否启用自动调整
            logger: 日志记录器
        """
        super().__init__(
            priority_list=initial_priority_list,
            enable_fallback=True,
            logger=logger
        )
        self.name = "dynamic_priority"
        self.performance_threshold = performance_threshold
        self.adjustment_enabled = adjustment_enabled
        
        # 性能记录
        self.performance_scores: Dict[str, float] = {
            adapter: 1.0 for adapter in initial_priority_list
        }
    
    def update_performance(self, adapter_name: str, score: float):
        """
        更新适配器性能分数
        
        Args:
            adapter_name: 适配器名称
            score: 性能分数 (0-1)
        """
        old_score = self.performance_scores.get(adapter_name, 1.0)
        # 使用指数移动平均
        self.performance_scores[adapter_name] = 0.7 * old_score + 0.3 * score
        
        self.logger.debug(
            f"适配器 {adapter_name} 性能更新: {old_score:.2f} -> "
            f"{self.performance_scores[adapter_name]:.2f}"
        )
        
        # 如果启用自动调整，重新排序
        if self.adjustment_enabled:
            self._adjust_priority()
    
    def _adjust_priority(self):
        """根据性能分数调整优先级"""
        # 按性能分数降序排列
        sorted_adapters = sorted(
            self.priority_list,
            key=lambda x: self.performance_scores.get(x, 0.5),
            reverse=True
        )
        
        if sorted_adapters != self.priority_list:
            old_list = self.priority_list.copy()
            self.priority_list = sorted_adapters
            self.logger.info(f"优先级自动调整: {old_list} -> {sorted_adapters}")
    
    def get_performance_score(self, adapter_name: str) -> float:
        """
        获取适配器性能分数
        
        Args:
            adapter_name: 适配器名称
        
        Returns:
            float: 性能分数
        """
        return self.performance_scores.get(adapter_name, 0.5)

